package com.axend.vetwavve.fragment

import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleCoroutineScope
import com.axend.lib_base.base.fragment.BaseVVDFragment
import com.axend.lib_base.bean.DefaultThresholdType.Companion.getDefaultThresholdType
import com.axend.lib_base.bean.SpeciesType
import com.axend.lib_base.bean.TempType
import com.axend.lib_base.engine.toast.toast
import com.axend.lib_base.ext.celsiusToFahrenheit
import com.axend.lib_base.ext.celsiusToFahrenheitNoAdd32
import com.axend.lib_base.ext.fahrenheitToCelsius
import com.axend.lib_base.ext.fahrenheitToCelsiusNoSub32
import com.axend.lib_base.ext.isPreFragment
import com.axend.lib_base.ext.kgToLbs
import com.axend.lib_base.ext.lbsToKg
import com.axend.lib_base.ext.preloadFragment
import com.axend.lib_base.ext.replaceFragment
import com.axend.lib_base.ext.roundToFloatOneDecimal
import com.axend.lib_base.ext.roundToNearestInteger
import com.axend.lib_base.ext.roundToOneDecimalPlace
import com.axend.lib_base.ext.showPreloadFragment
import com.axend.lib_base.ext.toFloatOrDefault
import com.axend.lib_base.ext.toPlainStringNoRounding
import com.axend.lib_base.ext.toStrOrDefault
import com.axend.lib_base.utils.DateUtils
import com.axend.lib_base.utils.DateUtils.calculateAge
import com.axend.lib_base.utils.DateUtils.getCurrentTimeStamp
import com.axend.lib_base.utils.ScreenAutoAdapter
import com.axend.lib_base.view.input.CustomInputView
import com.axend.lib_base.view.timepicker.BottomTimeDialogFragment
import com.axend.lib_room.entity.PetInfoEntity
import com.axend.lib_service.Constant.designSize
import com.axend.vetwavve.BR
import com.axend.vetwavve.R
import com.axend.vetwavve.activity.MainActivity
import com.axend.vetwavve.databinding.FragmentAddEditRecordBinding
import com.axend.vetwavve.fragment.startmonitoring.StartMonitoringFragment
import com.axend.vetwavve.viewmodel.AddOrEditRecordViewModel
import com.google.android.flexbox.FlexboxLayout
import com.jzxiang.pickerview.data.Type
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * @description 新增/编辑记录
 * @author admins
 * @time 2024/6/13 11:25
 */
class AddOrEditRecordFragment :
    BaseVVDFragment<AddOrEditRecordViewModel, FragmentAddEditRecordBinding>() {

    private var petInfo: PetInfoEntity? = null
    private var fromFragment: String? = null
    /*心率阈值*/
    private val MAX_HEART_VALUE = 140f
    private val MIN_HEART_VALUE = 50f

    /*阈值呼吸*/
    private val MAX_BREATH_VALUE = 40f
    private val MIN_BREATH_VALUE = 5f

    /*阈值摄氏度*/
    private val MAX_TEMP_VALUE = 45f
    private val MIN_TEMP_VALUE = 25f

    /*阈值华氏度*/
    private val MAX_TEMP_F_VALUE = 113f
    private val MIN_TEMP_F_VALUE = 77f


    data class LimitCheck(
        val limit: CustomInputView,
        val lower: CustomInputView,
        val warningMessageResId: Int
    )

    data class singleValueLimitCheck(
        val limit: CustomInputView,
        val warningMessageResId: Int
    )

    companion object {
        const val ARGUMENT_OPERATION = "operation"
        const val ARGUMENT_PET_INFO = "petInfo"
        const val ARGUMENT_FROM_FRAGMENT = "fromFragment"
        const val PARAMS_ADD = 0;
        const val PARAMS_EDIT = 1;

        fun newInstance(
            params: Int,
            petInfo: PetInfoEntity? = null,
            fromFragment: Fragment? = null
        ): AddOrEditRecordFragment {
            return AddOrEditRecordFragment().apply {
                arguments = Bundle().apply {
                    putInt(ARGUMENT_OPERATION, params)
                    if (petInfo != null) putParcelable(ARGUMENT_PET_INFO, petInfo)
                    putString(ARGUMENT_FROM_FRAGMENT, fromFragment!!::class.java.simpleName)

                }
            }
        }
    }

    override fun getBindingVariable(): Int = BR.viewmodel

    override fun init(savedInstanceState: Bundle?) {
        /*获取参数*/
        val params = arguments?.getInt(ARGUMENT_OPERATION) ?: PARAMS_ADD
        mViewModel.setIsAdd(params == PARAMS_ADD)
        if (params == PARAMS_EDIT) {
            petInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                arguments?.getParcelable(
                    ARGUMENT_PET_INFO,
                    PetInfoEntity::class.java
                )
            } else {
                arguments?.getParcelable(
                    ARGUMENT_PET_INFO
                )
            }
            fromFragment = arguments?.getString(ARGUMENT_FROM_FRAGMENT)
            if (fromFragment.equals(StartMonitoringFragment::class.java.simpleName)) {
                titleBarBinding.llBegin.visibility = android.view.View.GONE
            } else {
                titleBarBinding.llBegin.visibility = android.view.View.VISIBLE
            }

        } else {
            titleBarBinding.llBegin.visibility = android.view.View.VISIBLE
            titleBarBinding.llBegin.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_colorprimary_enable)
            mBinding.cvName.setOnEditChange {
                if (it.isNullOrEmpty())
                    titleBarBinding.llBegin.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_colorprimary_enable)
                else
                    titleBarBinding.llBegin.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_colorprimary)
            }
            mBinding.cvName.setTvTitle(
                getString(com.axend.lib_base.R.string.app_info_name),
                ContextCompat.getColor(
                    requireContext(),
                    com.axend.lib_base.R.color.text_red_level_2
                ),
                "*",
                4
            )

            mBinding.cvSpecies.setTvTitle(
                getString(com.axend.lib_base.R.string.app_info_species),
                ContextCompat.getColor(
                    requireContext(),
                    com.axend.lib_base.R.color.text_red_level_2
                ),
                "*",
                7
            )
            /*物种选择*/
            mBinding.cvSpecies.setOnSpinnerItemSelectedListener { parent, view, position, id ->
                selectSpecies(position)
            }
            /*温度选择默认F*/
            mBinding.cvTempCalibration.spinnerPosition = 1
            /*体动默认关闭*/
            mBinding.cvAlarmMove.switchStatus = false
            /*出框默认打开*/
            mBinding.cvAlarmFaceMotion.switchStatus = true
            /*初始化物种默认值*/
            selectSpecies(0)
        }

        titleBarBinding.ivBack.setOnClickListener {
            if (!fromFragment.isNullOrEmpty() && fromFragment.equals(StartMonitoringFragment::class.java.simpleName)) {
                checkAndCommitParams(params)
            } else {
                (requireActivity() as? MainActivity)?.onBack()
            }
        }

        /*日期选择弹窗*/
        mBinding.cvBirthday.setOnSpinnerClickListener {
            val minMillseconds: Long = 2539387586000// 默认最小年份2010年
            val fragment = BottomTimeDialogFragment.Builder()
                .setType(Type.YEAR_MONTH_DAY)
                .setMinMillseconds(1277083586000) //最小2010
                .setMaxMillseconds(getCurrentTimeStamp())
                .setCurrentMillseconds(1434849986000) // 默认2015年
                .setWheelItemTextSize(30)
                .setThemeColor(
                    ContextCompat.getColor(
                        requireContext(),
                        com.axend.lib_base.R.color.colorPrimary
                    )
                )
                .setDayText("")
                .setYearText("")
                .setCallBack { timePickerView, date ->
                    mBinding.cvBirthday.spinnerText = date.toString()
                }
                .build()
            fragment.show(childFragmentManager, BottomTimeDialogFragment::class.java.simpleName)
        }

        /*处理验证*/
        titleBarBinding.llBegin.setOnClickListener {
            checkAndCommitParams(params)
        }
        /*温度单位转换*/
        mBinding.spTemperatureUnit.setOnSpinnerItemSelectedListener { parent, view, position, id ->
            if (position == 0) {
                /*摄氏度转华氏度*/
                if (mBinding.cvTempCalibration.editText.toString().isNotEmpty()) {
                    mBinding.cvTempCalibration.editText =
                        mBinding.cvTempCalibration.editText.toFloatOrDefault(0f)
                            .celsiusToFahrenheitNoAdd32().toPlainStringNoRounding()
                }
                mBinding.cvTempAlarmLimit.editText =
                    mBinding.cvTempAlarmLimit.editText.toFloatOrNull()?.celsiusToFahrenheit()
                        ?.toPlainStringNoRounding()
                mBinding.cvTempAlarmLower.editText =
                    mBinding.cvTempAlarmLower.editText.toFloatOrNull()?.celsiusToFahrenheit()
                        ?.toPlainStringNoRounding()
                mBinding.cvTempWarningLimit.editText =
                    mBinding.cvTempWarningLimit.editText.toFloatOrNull()?.celsiusToFahrenheit()
                        ?.toPlainStringNoRounding()
                mBinding.cvTempWarningLower.editText =
                    mBinding.cvTempWarningLower.editText.toFloatOrNull()?.celsiusToFahrenheit()
                        ?.toPlainStringNoRounding()
            } else {
                /*华氏度转摄氏度*/
                if (mBinding.cvTempCalibration.editText.toString().isNotEmpty()) {
                    mBinding.cvTempCalibration.editText =
                        mBinding.cvTempCalibration.editText.toFloatOrDefault(0f)
                            .fahrenheitToCelsiusNoSub32().toPlainStringNoRounding()
                }
                mBinding.cvTempAlarmLimit.editText =
                    mBinding.cvTempAlarmLimit.editText.toFloatOrNull()?.fahrenheitToCelsius()
                        ?.toPlainStringNoRounding()
                mBinding.cvTempAlarmLower.editText =
                    mBinding.cvTempAlarmLower.editText.toFloatOrNull()?.fahrenheitToCelsius()
                        ?.toPlainStringNoRounding()
                mBinding.cvTempWarningLimit.editText =
                    mBinding.cvTempWarningLimit.editText.toFloatOrNull()?.fahrenheitToCelsius()
                        ?.toPlainStringNoRounding()
                mBinding.cvTempWarningLower.editText =
                    mBinding.cvTempWarningLower.editText.toFloatOrNull()?.fahrenheitToCelsius()
                        ?.toPlainStringNoRounding()

            }
        }
        /*重量单位转换*/
        mBinding.spWeightUnit.setOnSpinnerItemSelectedListener { parent, view, position, id ->
            if (position == 0) {
                /*kg转lbs*/
                if (mBinding.cvWeight.editText.toString().isNotEmpty()) {
                    mBinding.cvWeight.editText =
                        mBinding.cvWeight.editText.toFloatOrDefault(0f)
                            .kgToLbs().toPlainStringNoRounding()
                }
            } else {
                /*lbs转kg*/
                if (mBinding.cvWeight.editText.toString().isNotEmpty()) {
                    mBinding.cvWeight.editText =
                        mBinding.cvWeight.editText.toFloatOrDefault(0f)
                            .lbsToKg().toPlainStringNoRounding()
                }
            }
        }


    }

    private fun checkThresholdsValue(
        minValue: Float,
        maxValue: Float,
        inputView: CustomInputView,
        warningMessageResId: Int
    ): Boolean {
        if (inputView.editText.isEmpty()){
            inputView.setEditTextRedTipsBackground(true)
            return true
        }
        if (inputView.editText.toFloatOrDefault(0f) < minValue || inputView.editText.toFloatOrDefault(
                0f
            ) > maxValue
        ) {
            inputView.setEditTextRedTipsBackground(true)
            toast(getString(warningMessageResId))
            return true //true则代表有异常
        }
        inputView.setEditTextRedTipsBackground(false)
        return false
    }

    /**
     * 物种默认值
     */
    private fun selectSpecies(position: Int) {
        /*呼吸默认值设定*/
        mBinding.cvBreathAlarmLimit.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).breathUpLimit.roundToOneDecimalPlace()
        mBinding.cvBreathAlarmLower.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).breathLowLimit.roundToOneDecimalPlace()
        mBinding.cvBreathWarningLimit.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).breathWarningUpLimit.roundToOneDecimalPlace()
        mBinding.cvBreathWarningLower.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).breathWarningLowLimit.roundToOneDecimalPlace()
        /*心率默认值设定*/
        mBinding.cvHeartAlarmLimit.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).heartAlarmUpLimit.roundToOneDecimalPlace()
        mBinding.cvHeartAlarmLower.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).heartAlarmLowLimit.roundToOneDecimalPlace()
        mBinding.cvHeartWarningLimit.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).heartWarningUpLimit.roundToOneDecimalPlace()
        mBinding.cvHeartWarningLower.editText =
            getDefaultThresholdType(SpeciesType.getSpeciesType(position)).heartWarningLowLimit.roundToOneDecimalPlace()
        /*温度默认值设定*/
        mBinding.cvTempAlarmLimit.editText = TempType.getTempType(
            SpeciesType.getSpeciesType(position),
            mBinding.spTemperatureUnit.selectedIndex
        ).temperatureUpLimit.roundToNearestInteger().toString()
        mBinding.cvTempAlarmLower.editText = TempType.getTempType(
            SpeciesType.getSpeciesType(position),
            mBinding.spTemperatureUnit.selectedIndex
        ).temperatureLowLimit.roundToNearestInteger().toString()
        mBinding.cvTempWarningLimit.editText = TempType.getTempType(
            SpeciesType.getSpeciesType(position),
            mBinding.spTemperatureUnit.selectedIndex
        ).temperatureWarningUpLimit.roundToNearestInteger().toString()
        mBinding.cvTempWarningLower.editText = TempType.getTempType(
            SpeciesType.getSpeciesType(position),
            mBinding.spTemperatureUnit.selectedIndex
        ).temperatureWarningLowLimit.roundToNearestInteger().toString()
    }


    /**
     * 检查参数并且提交
     */
    private fun checkAndCommitParams(params: Int) {
        when (params) {
            PARAMS_ADD -> {
                mBinding.cvName.setEditTextRedTipsBackground(mBinding.cvName.editText.isNullOrEmpty())
                if (mBinding.cvName.editText.trim().isNullOrEmpty()) {
                    return toast(
                        getString(
                            com.axend.lib_base.R.string.app_tips_value_null,
                            getString(com.axend.lib_base.R.string.app_info_name)
                        )
                    )
                }
            }
        }

        /*心率呼吸等组件判空*/
        if (!customViewsNullCheck(mBinding.llHeartRate)) return
        val heartCheck = listOf(
            LimitCheck(
                mBinding.cvHeartAlarmLimit,
                mBinding.cvHeartWarningLimit,
                com.axend.lib_base.R.string.app_tips_alarm_warning_up_greater
            ),
            LimitCheck(
                mBinding.cvHeartWarningLimit,
                mBinding.cvHeartWarningLower,
                com.axend.lib_base.R.string.app_tips_warning_greater
            ),
            LimitCheck(
                mBinding.cvHeartWarningLower,
                mBinding.cvHeartAlarmLower,
                com.axend.lib_base.R.string.app_tips_alarm_warning_low_greater
            )
        )
        val heartHasError = heartCheck.any { check ->
            checkLimitAndWarn(
                check.limit,
                check.lower,
                check.warningMessageResId
            )
        }
        if (heartHasError) return

        if (!customViewsNullCheck(mBinding.llBreathingRate)) return
        /*呼吸范围值*/
        val breathSingleCheck = listOf(
            singleValueLimitCheck(
                mBinding.cvBreathAlarmLower,
                com.axend.lib_base.R.string.app_tips_heart_value_limit
            ),
            singleValueLimitCheck(
                mBinding.cvBreathAlarmLower,
                com.axend.lib_base.R.string.app_tips_heart_value_limit
            ),
        )
        val hasSingleBreathError = breathSingleCheck.any { check ->
            checkThresholdsValue(
                MIN_BREATH_VALUE,
                MAX_BREATH_VALUE,
                check.limit,
                check.warningMessageResId
            )
        }
        if (hasSingleBreathError) return

        val breathCheck = listOf(
            LimitCheck(
                mBinding.cvBreathAlarmLimit,
                mBinding.cvBreathWarningLimit,
                com.axend.lib_base.R.string.app_tips_alarm_warning_up_greater
            ),
            LimitCheck(
                mBinding.cvBreathWarningLimit,
                mBinding.cvBreathWarningLower,
                com.axend.lib_base.R.string.app_tips_warning_greater
            ),

            LimitCheck(
                mBinding.cvBreathWarningLower,
                mBinding.cvBreathAlarmLower,
                com.axend.lib_base.R.string.app_tips_alarm_warning_low_greater
            ),
        )
        val breathHasError = breathCheck.any { check ->
            checkLimitAndWarn(
                check.limit,
                check.lower,
                check.warningMessageResId
            )
        }
        if (breathHasError) return

        if (!customViewsNullCheck(mBinding.llTemperature)) return
        /*呼吸范围值*/
        val tempSingleCheck = listOf(
            singleValueLimitCheck(
                mBinding.cvTempAlarmLower,
                if (mBinding.spTemperatureUnit.selectedIndex == 1) com.axend.lib_base.R.string.app_tips_temp_value_limit else com.axend.lib_base.R.string.app_tips_temp_f_value_limit
            ),
            singleValueLimitCheck(
                mBinding.cvTempAlarmLimit,
                if (mBinding.spTemperatureUnit.selectedIndex == 1) com.axend.lib_base.R.string.app_tips_temp_value_limit else com.axend.lib_base.R.string.app_tips_temp_f_value_limit
            ),
        )
        val hasSingleTempError = tempSingleCheck.any { check ->
            checkThresholdsValue(
                if (mBinding.spTemperatureUnit.selectedIndex == 1) MIN_TEMP_VALUE else MIN_TEMP_F_VALUE,
                if (mBinding.spTemperatureUnit.selectedIndex == 1) MAX_TEMP_VALUE else MAX_TEMP_F_VALUE,
                check.limit,
                check.warningMessageResId
            )
        }
        if (hasSingleTempError) return

        val tempCheck = listOf(
            LimitCheck(
                mBinding.cvTempAlarmLimit,
                mBinding.cvTempWarningLimit,
                com.axend.lib_base.R.string.app_tips_alarm_warning_up_greater
            ),
            LimitCheck(
                mBinding.cvTempWarningLimit,
                mBinding.cvTempWarningLower,
                com.axend.lib_base.R.string.app_tips_warning_greater
            ),

            LimitCheck(
                mBinding.cvTempWarningLower,
                mBinding.cvTempAlarmLower,
                com.axend.lib_base.R.string.app_tips_alarm_warning_low_greater
            ),
        )

        val tempHasError = tempCheck.any { check ->
            checkLimitAndWarn(check.limit, check.lower, check.warningMessageResId)
        }

        if (tempHasError) return



        insertOrUpdatePetInfo(params)
    }


    private fun insertOrUpdatePetInfo(params: Int) {
        when (params) {
            PARAMS_ADD -> {
                /*开始监测*/
                showStateLoading()
                mViewModel.submitParamsToDataBase(PetInfoEntity().apply {
                    petNickName = mBinding.cvName.editText
                    masterName = mBinding.cvMaster.editText
                    species = mBinding.cvSpecies.spinnerPosition//物种
                    speciesValue = mBinding.cvSpecies.spinnerText
                    breed = mBinding.cvBreed.editText//品种
                    sex = mBinding.cvSex.spinnerPosition
                    birthday = mBinding.cvBirthday.spinnerContent
                    try {
                        age = calculateAge(mBinding.cvBirthday.spinnerContent).toFloatOrDefault(0f)
                    } catch (e: Exception) {
                        return toast(getString(com.axend.lib_base.R.string.app_tips_birthday))
                    }
                    weight = mBinding.cvWeight.editText.toFloatOrDefault(0f)
                    /*心率警报阈值*/
                    heartAlarmLimit = mBinding.cvHeartAlarmLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    heartAlarmLower = mBinding.cvHeartAlarmLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    /*呼吸警报阈值*/
                    breathAlarmLimit = mBinding.cvBreathAlarmLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    breathAlarmLower = mBinding.cvBreathAlarmLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    temperatureUnit = mBinding.spTemperatureUnit.selectedIndex
                    weightUnit = mBinding.spWeightUnit.selectedIndex
                    /*心率告警阈值*/
                    heartWarningLimit = mBinding.cvHeartWarningLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    heartWarningLower = mBinding.cvHeartWarningLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    /*呼吸告警阈值*/
                    breathWarningLimit = mBinding.cvBreathWarningLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    breathWarningLower = mBinding.cvBreathWarningLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    tempAlarmLimit =
                        mBinding.cvTempAlarmLimit.editText.toFloatOrNull()?.roundToFloatOneDecimal()
                    tempAlarmLower =
                        mBinding.cvTempAlarmLower.editText.toFloatOrNull()?.roundToFloatOneDecimal()
                    tempWarningLimit = mBinding.cvTempWarningLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    tempWarningLower = mBinding.cvTempWarningLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    tempCalibration = mBinding.cvTempCalibration.editText.toFloatOrDefault(0f)
                    alarmSetting = if (mBinding.cvAlarmMove.switchStatus) 0 else 1
                    faceMoveAlarmSetting = if (mBinding.cvAlarmFaceMotion.switchStatus) 0 else 1
                    /*长度单位*/
                    lengthUnit = mBinding.cvLength.spinnerPosition
                    lengthUnitStr =
                        resources.getStringArray(com.axend.lib_base.R.array.app_length_unit)[lengthUnit]
                }) {
                    showStateSuccess()
//                    replaceFragment(
//                        requireActivity(),
//                        (requireActivity() as MainActivity).getFragmentContainerId(),
//                        WaitControlFragment.newInstance(it),
//                        this@AddOrEditRecordFragment,
//                        null,
//                        true
//                    )

                    CoroutineScope(Dispatchers.Main).launch {
                        titleBarBinding.tvWaitControl.setText(com.axend.lib_base.R.string.app_wait_control_loading)
                        titleBarBinding.progressBar.visibility = View.VISIBLE
                        val nextFragment = WaitControlFragment.newInstance(it)
                        preloadFragment(
                            requireActivity(),
                            (requireActivity() as MainActivity).getFragmentContainerId(),
                            nextFragment,
                            null
                        )

                        delay(4000)
                        showPreloadFragment(
                            requireActivity(),
                            (requireActivity() as MainActivity).getFragmentContainerId(),
                            nextFragment,
                            this@AddOrEditRecordFragment,
                            null,
                        )
                        titleBarBinding.tvWaitControl.setText(com.axend.lib_base.R.string.app_info_begin)
                        titleBarBinding.progressBar.visibility = View.GONE
                    }

                }
            }

            PARAMS_EDIT -> {
                mViewModel.updateParamsToDataBase(petInfo?.apply {
                    weight = mBinding.cvWeight.editText.toFloatOrDefault(0f)
                    /*心率警报阈值*/
                    heartAlarmLimit = mBinding.cvHeartAlarmLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    heartAlarmLower = mBinding.cvHeartAlarmLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    /*呼吸警报阈值*/
                    breathAlarmLimit = mBinding.cvBreathAlarmLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    breathAlarmLower = mBinding.cvBreathAlarmLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    temperatureUnit = mBinding.spTemperatureUnit.selectedIndex
                    weightUnit = mBinding.spWeightUnit.selectedIndex
                    /*心率告警阈值*/
                    heartWarningLimit = mBinding.cvHeartWarningLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    heartWarningLower = mBinding.cvHeartWarningLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    /*呼吸告警阈值*/
                    breathWarningLimit = mBinding.cvBreathWarningLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    breathWarningLower = mBinding.cvBreathWarningLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    tempAlarmLimit =
                        mBinding.cvTempAlarmLimit.editText.toFloatOrNull()?.roundToFloatOneDecimal()
                    tempAlarmLower =
                        mBinding.cvTempAlarmLower.editText.toFloatOrNull()?.roundToFloatOneDecimal()
                    tempWarningLimit = mBinding.cvTempWarningLimit.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    tempWarningLower = mBinding.cvTempWarningLower.editText.toFloatOrNull()
                        ?.roundToFloatOneDecimal()
                    tempCalibration = mBinding.cvTempCalibration.editText.toFloatOrDefault(0f)
                    alarmSetting = if (mBinding.cvAlarmMove.switchStatus) 0 else 1
                    faceMoveAlarmSetting = if (mBinding.cvAlarmFaceMotion.switchStatus) 0 else 1
                    /*长度单位*/
                    lengthUnit = mBinding.cvLength.spinnerPosition
                    lengthUnitStr =
                        resources.getStringArray(com.axend.lib_base.R.array.app_length_unit)[lengthUnit]
                }!!) {
                    showStateSuccess()
                    if (fromFragment.isNullOrEmpty() || fromFragment == StartMonitoringFragment::class.java.simpleName) {
                        (requireActivity() as MainActivity).onBack()
                    } else {
//                        replaceFragment(
//                            requireActivity(),
//                            (requireActivity() as MainActivity).getFragmentContainerId(),
//                            WaitControlFragment.newInstance(it),
//                            this@AddOrEditRecordFragment,
//                            null,
//                            true
//                        )
                        CoroutineScope(Dispatchers.Main).launch {
                            titleBarBinding.tvWaitControl.setText(com.axend.lib_base.R.string.app_wait_control_loading)
                            titleBarBinding.progressBar.visibility = View.VISIBLE
                            val nextFragment = WaitControlFragment.newInstance(it)
                            preloadFragment(
                                requireActivity(),
                                (requireActivity() as MainActivity).getFragmentContainerId(),
                                nextFragment,
                                null
                            )

                            delay(4000)
                            showPreloadFragment(
                                requireActivity(),
                                (requireActivity() as MainActivity).getFragmentContainerId(),
                                nextFragment,
                                this@AddOrEditRecordFragment,
                                null,
                            )
                            titleBarBinding.tvWaitControl.setText(com.axend.lib_base.R.string.app_info_begin)
                            titleBarBinding.progressBar.visibility = View.GONE
                        }

                    }
//                    toast("update success!")
                }
            }
        }

    }


    /**
     * 组件遍历null判断
     */
    private fun customViewsNullCheck(view: ViewGroup): Boolean {
        var hasNonNullInput = false // 标记是否有非空输入
        var hasNullInput = false // 标记是否有空输入
        var inputViewList: MutableList<CustomInputView> = mutableListOf()

        for (i in 0 until view.childCount) {
            val viewChild = view.getChildAt(i)
            if (viewChild is FlexboxLayout) {
                for (j in 0 until viewChild.childCount) {
                    val customView = viewChild.getChildAt(j)
                    if (customView is CustomInputView) {
                        inputViewList.add(customView)
                        if (customView.editText.isNullOrEmpty()) {
                            hasNullInput = true
                            customView.setEditTextRedTipsBackground(true)
                        } else {
                            hasNonNullInput = true
                            customView.setEditTextRedTipsBackground(false)
                        }
                    }
                }
            }
        }

        // 如果有非空输入，检查是否有空输入
        if (hasNullInput) {
            toast(getString(com.axend.lib_base.R.string.app_tips_number_null))
            return false
        }

        // 如果没有非空输入，即所有输入都为空，或者所有输入都不为空，都视为通过
        for (customView in inputViewList) {
            customView.setEditTextRedTipsBackground(false)
        }
        return true
    }


    /**
     * 组件值比较
     */
    private fun checkLimitAndWarn(
        limit: CustomInputView,
        lower: CustomInputView,
        warningMessageResId: Int
    ): Boolean {
        if (limit.editText.isNullOrEmpty() && lower.editText.isNullOrEmpty()) return false


        val limitValue = limit.editText.toFloatOrDefault(0f)
        val lowerValue = lower.editText.toFloatOrDefault(0f)

        /*心率做范围判断*/
        if (limit.id == mBinding.cvHeartAlarmLimit.id || lower.id == mBinding.cvHeartAlarmLower.id) {
            if (mBinding.cvHeartAlarmLimit.editText.toFloatOrDefault(0f) - mBinding.cvHeartAlarmLower.editText.toFloatOrDefault(
                    0f
                ) <= 50
            ) {
                mBinding.cvHeartAlarmLimit.setEditTextRedTipsBackground(true)
                mBinding.cvHeartAlarmLower.setEditTextRedTipsBackground(true)
                toast(getString(com.axend.lib_base.R.string.app_tips_heart_value_limit))
                return true
            }
        }


        if (limitValue <= lowerValue) {
            limit.setEditTextRedTipsBackground(true)
            lower.setEditTextRedTipsBackground(true)
            toast(getString(warningMessageResId))
            return true // 表示有错误发生
        }

        limit.setEditTextRedTipsBackground(false)
        lower.setEditTextRedTipsBackground(false)
        return false // 没有错误
    }


    override fun onResume() {
        super.onResume()
        ScreenAutoAdapter.match(requireActivity(), designSize)
        /*edit在Resume时调用*/
        petInfo?.let {
            mBinding.cvName.setContentText(it.petNickName)
            mBinding.cvMaster.setContentText(it.masterName)
            mBinding.cvSex.setContentText(resources.getStringArray(com.axend.lib_base.R.array.app_sex_type)[it.sex])
            mBinding.cvSpecies.setContentText(resources.getStringArray(com.axend.lib_base.R.array.app_pet_types)[it.species])
            mBinding.cvBirthday.setContentText(it.birthday)
            mBinding.cvBreed.setContentText(it.breed)

            mBinding.cvWeight.editText = it.weight.toString()
            mBinding.spWeightUnit.selectedIndex = it.weightUnit

            mBinding.cvBreathAlarmLimit.editText =
                (it.breathAlarmLimit?.roundToNearestInteger() ?: "").toString()
            mBinding.cvBreathAlarmLower.editText =
                (it.breathAlarmLower?.roundToNearestInteger() ?: "").toString()

            /*心率警告*/
            mBinding.cvHeartWarningLimit.editText =
                (it.heartWarningLimit?.roundToNearestInteger() ?: "").toString()
            mBinding.cvHeartWarningLower.editText =
                (it.heartWarningLower?.roundToNearestInteger() ?: "").toString()
            /*呼吸报警*/
            mBinding.cvHeartAlarmLimit.editText =
                (it.heartAlarmLimit?.roundToNearestInteger() ?: "").toString()
            mBinding.cvHeartAlarmLower.editText =
                (it.heartAlarmLower?.roundToNearestInteger() ?: "").toString()
            /*呼吸警告*/
            mBinding.cvBreathWarningLimit.editText =
                (it.breathWarningLimit?.roundToNearestInteger() ?: "").toString()
            mBinding.cvBreathWarningLower.editText =
                (it.breathWarningLower?.roundToNearestInteger() ?: "").toString()
            /*温度报警*/
            mBinding.cvTempAlarmLimit.editText =
                (it.tempAlarmLimit?.toPlainStringNoRounding() ?: "").toString()
            mBinding.cvTempAlarmLower.editText =
                (it.tempAlarmLower?.toPlainStringNoRounding() ?: "").toString()
            /*温度警告*/
            mBinding.cvTempWarningLimit.editText =
                (it.tempWarningLimit?.toPlainStringNoRounding() ?: "").toString()
            mBinding.cvTempWarningLower.editText =
                (it.tempWarningLower?.toPlainStringNoRounding() ?: "").toString()
            mBinding.spTemperatureUnit.selectedIndex = it.temperatureUnit
            mBinding.cvAlarmMove.switchStatus = it.alarmSetting == 0
            mBinding.cvAlarmFaceMotion.switchStatus = it.faceMoveAlarmSetting == 0
            mBinding.cvTempCalibration.editText = (it.tempCalibration ?: "").toString()
            /*长度单位*/
            mBinding.cvLength.spinnerPosition = it.lengthUnit
        }
        /*呼吸值*/
        mBinding.cvBreathAlarmLower.setOnEditChange {
            checkThresholdsValue(
                MIN_BREATH_VALUE,
                MAX_BREATH_VALUE,
                mBinding.cvBreathAlarmLower,
                com.axend.lib_base.R.string.app_tips_heart_value_limit
            )
        }
        mBinding.cvBreathAlarmLimit.setOnEditChange {
            checkThresholdsValue(
                MIN_BREATH_VALUE,
                MAX_BREATH_VALUE,
                mBinding.cvBreathAlarmLimit,
                com.axend.lib_base.R.string.app_tips_heart_value_limit
            )
        }
        /*温度*/
        mBinding.cvTempAlarmLower.setOnEditChange {
            if (mBinding.spTemperatureUnit.selectedIndex == 1) {
                checkThresholdsValue(
                    MIN_TEMP_VALUE,
                    MAX_TEMP_VALUE,
                    mBinding.cvTempAlarmLower,
                    com.axend.lib_base.R.string.app_tips_temp_value_limit
                )
            } else {
                checkThresholdsValue(
                    MIN_TEMP_F_VALUE,
                    MAX_TEMP_F_VALUE,
                    mBinding.cvTempAlarmLower,
                    com.axend.lib_base.R.string.app_tips_temp_f_value_limit
                )
            }

        }
        mBinding.cvTempAlarmLimit.setOnEditChange {
            if (mBinding.spTemperatureUnit.selectedIndex == 1) {
                checkThresholdsValue(
                    MIN_TEMP_VALUE,
                    MAX_TEMP_VALUE,
                    mBinding.cvTempAlarmLimit,
                    com.axend.lib_base.R.string.app_tips_temp_value_limit
                )
            } else {
                checkThresholdsValue(
                    MIN_TEMP_F_VALUE,
                    MAX_TEMP_F_VALUE,
                    mBinding.cvTempAlarmLimit,
                    com.axend.lib_base.R.string.app_tips_temp_f_value_limit
                )
            }
        }
    }

}